package com.koron.standard.jobStock.excel;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.koron.bean.base.Response;
import com.koron.common.core.business.datadict.utils.DataDictTool;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.standard.deviceClasssify.bean.po.Type;
import com.koron.standard.deviceClasssify.service.TypeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author jzp
 * @since 2022/2/23
 */
@Slf4j
public abstract class JobStockListener extends AnalysisEventListener<Map<Integer, String>> {
    private final TypeService typeService;
    private final Map<String, Integer> standardCheckLevel;
    private final String appId;
    private final List<String> sheetNames;
    private final List<String> ids;
    private String currentSheetName;
    private String errorMessage;
    private boolean skipped;

    public JobStockListener(TypeService typeService){
        this.typeService = typeService;
        Map<String, String> dataDictByCode = DataDictTool.getDataDictByCode("standardManagement", "standard_check_level");
        standardCheckLevel = dataDictByCode.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, e -> Integer.valueOf(e.getKey())));
        appId = ThreadLocalContext.getLoginUser().getAppId();
        sheetNames = new ArrayList<>();
        ids = new ArrayList<>();
    }

    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        super.invokeHeadMap(headMap, context);
        currentSheetName = context.readSheetHolder().getSheetName();
        log.info("读取sheet：{}", currentSheetName);
        resetData();
        if (StringUtils.isEmpty(currentSheetName) || currentSheetName.equals(templateSheetName())) {
            skipped = true;
            return;
        }
        skipped = false;
        invoke(headMap, context);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        if (skipped) {
            return;
        }
        log.info("保存sheet：{}", currentSheetName);
        ids.add(saveData());
        sheetNames.add(currentSheetName);
    }

    public abstract String saveData();
    public abstract void resetData();
    public abstract String templateSheetName();

    public String getIdByTypeCode(String typeCode) {
        if (StringUtils.isEmpty(typeCode)) {
            errorMessage += "  "+currentSheetName + "的设备分类编码" + typeCode + "为空";
            skipped = true;
            return null;
        }
        Type type = typeService.getByCode(typeCode.trim());
        if (type == null) {
            errorMessage += "  "+currentSheetName + "的设备分类编码" + typeCode + "不存在";
            skipped = true;
            return null;
        }
        return type.getId();
    }

    /**
     * 氨氮(mg/L)
     * pH值(pH)
     * ->
     * [氨氮,mg/L],[pH值,pH]
     */
    public List<String[]> resolveItemStr(String str, String delimit) {
        if (StringUtils.isEmpty(str)) {
            return new ArrayList<>();
        }

        String[] split = str.split(delimit);
        ArrayList<String[]> list = new ArrayList<>();
        Pattern compile = Pattern.compile("(.+)[(|（](.*)[)|）]");
        for (String line : split) {
            Matcher matcher = compile.matcher(line.trim());
            if (matcher.find()) {
                list.add(new String[]{matcher.group(1), matcher.group(2)});
            }
        }
        return list;
    }

    public Integer getLevel(String source) {
        if (StringUtils.isEmpty(source)) {
            return null;
        }
        return standardCheckLevel.get(source);
    }

    public Response getSheetResponse() {
        if (StringUtils.isEmpty(errorMessage)) {
            return Response.ok("导入成功", ids);
        }
        Response<List<String>> response = new Response<>();
        response.setCode(5001);
        response.setDescription("导入成功的有：" + sheetNames.toString() + "；\n其中，" + errorMessage);
        response.setData(ids);
        return response;
    }

    public String getAppId() {
        return appId;
    }

    public boolean isSkipped() {
        return skipped;
    }

    public String getCurrentSheetName() {
        return currentSheetName;
    }

    public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
    }
}
